package com.gun.management.module.task.service.taskInfo;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.gson.Gson;
import com.gun.management.framework.common.exception.ServiceException;
import com.gun.management.framework.common.pojo.PageResult;
import com.gun.management.framework.common.util.object.BeanUtils;
import com.gun.management.framework.mybatis.core.util.MyBatisUtils;
import com.gun.management.module.member.api.point.MemberPointApi;
import com.gun.management.module.member.enums.point.MemberPointBizTypeEnum;
import com.gun.management.module.system.api.dict.DictDataApi;
import com.gun.management.module.task.controller.admin.taskInfo.vo.TaskInfoPageReqVO;
import com.gun.management.module.task.controller.admin.taskInfo.vo.TaskInfoRespVO;
import com.gun.management.module.task.controller.admin.taskInfo.vo.TaskInfoSaveReqVO;
import com.gun.management.module.task.controller.app.vo.AppTaskInfoPageReqVO;
import com.gun.management.module.task.controller.app.vo.AppTaskInfoRespVO;
import com.gun.management.module.task.controller.app.vo.AppTaskRetRespVO;
import com.gun.management.module.task.dal.dataobject.taskInfo.ShareContent;
import com.gun.management.module.task.dal.dataobject.taskInfo.TaskInfoDO;
import com.gun.management.module.task.dal.dataobject.taskRewardLog.TaskRewardLogDO;
import com.gun.management.module.task.dal.dataobject.taskRewardRecord.TaskRewardRecordDO;
import com.gun.management.module.task.dal.mysql.taskInfo.TaskInfoMapper;
import com.gun.management.module.task.dal.mysql.taskRewardLog.TaskRewardLogMapper;
import com.gun.management.module.task.dal.mysql.taskRewardRecord.TaskRewardRecordMapper;
import com.gun.management.module.task.enums.ContentTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import jakarta.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.gun.management.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.gun.management.framework.web.core.util.WebFrameworkUtils.getLoginUserId;
import static com.gun.management.module.task.enums.ErrorCodeConstants.TASK_INFO_NOT_EXISTS;

/**
 * 任务信息 Service 实现类
 *
 * @author 测试账号
 */
@Service
@Validated
@Slf4j
public class TaskInfoServiceImpl implements TaskInfoService {

    @Resource
    private TaskInfoMapper taskInfoMapper;


    @Resource
    private TaskRewardLogMapper rewardLogMapper;

    @Resource
    private TaskRewardRecordMapper  taskRewardRecordMapper;

    @Resource
    private MemberPointApi memberPointApi;

    @Resource
    private DictDataApi dictDataApi;

    @Override
    public Long createInfo(TaskInfoSaveReqVO createReqVO) {

        LambdaQueryWrapper<TaskInfoDO> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(TaskInfoDO::getName,createReqVO.getName());
        lambdaQueryWrapper.eq(TaskInfoDO::getDeleted,0);
        TaskInfoDO taskInfo = taskInfoMapper.selectOne(lambdaQueryWrapper);
        if (taskInfo != null) {
            throw new ServiceException(505,"任务名称已重复！");
        }

        if (createReqVO.getMaxRewardTimes() != -1 && createReqVO.getDayRewardTimes() != -1 && createReqVO.getMaxRewardTimes() < createReqVO.getDayRewardTimes()) {
            throw new ServiceException(506,"每天奖励次数不能大于累计最多奖励次数！");
        }

        // 插入
        TaskInfoDO taskInfoDO = BeanUtils.toBean(createReqVO, TaskInfoDO.class);


        if (createReqVO.getShareContentDetail() != null) {
            taskInfoDO.setShareContent(createReqVO.getShareContentDetail().toJsonString());
        }


        taskInfoMapper.insert(taskInfoDO);
        // 返回
        return taskInfoDO.getId();
    }

    @Override
    public void updateInfo(TaskInfoSaveReqVO updateReqVO) {
        // 校验存在
        validateInfoExists(updateReqVO.getId());
        // 更新
        TaskInfoDO updateObj = BeanUtils.toBean(updateReqVO, TaskInfoDO.class);

        if (updateReqVO.getShareContentDetail() != null) {
            updateObj.setShareContent(updateReqVO.getShareContentDetail().toJsonString());
        }

        if (updateReqVO.getMaxRewardTimes() != -1 && updateReqVO.getDayRewardTimes() != -1 && updateReqVO.getMaxRewardTimes() < updateReqVO.getDayRewardTimes()) {
            throw new ServiceException(506,"每天奖励次数不能大于累计最多奖励次数！");
        }

        taskInfoMapper.updateById(updateObj);
    }

    @Override
    public void deleteInfo(Long id) {
        // 校验存在
        validateInfoExists(id);


        LambdaUpdateWrapper<TaskInfoDO> taskInfoDOLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        taskInfoDOLambdaUpdateWrapper.eq(TaskInfoDO::getId,id);
        taskInfoDOLambdaUpdateWrapper.set(TaskInfoDO::getDeleted,1);
        // 伪删除
        taskInfoMapper.update(null,taskInfoDOLambdaUpdateWrapper);
    }

    private void validateInfoExists(Long id) {
        if (getInfo(id) == null) {
            throw exception(TASK_INFO_NOT_EXISTS);
        }
    }

    @Override
    public TaskInfoDO getInfo(Long id) {
        LambdaQueryWrapper<TaskInfoDO> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(TaskInfoDO::getId,id);
        lambdaQueryWrapper.eq(TaskInfoDO::getDeleted,0);

        return taskInfoMapper.selectById(id);
    }

    @Override
    public TaskInfoRespVO getTaskDetailById(Long id) {


        TaskInfoDO taskInfoDO =  getInfo(id);
        TaskInfoRespVO taskInfoRespVO = new TaskInfoRespVO();
        BeanUtils.copyProperties(taskInfoDO,taskInfoRespVO);

        if (taskInfoDO.getShareContent() != null) {
            Gson gSon = new Gson();
            ShareContent shareContent = gSon.fromJson(taskInfoDO.getShareContent(),ShareContent.class);
            taskInfoRespVO.setShareContentDetail(shareContent);
        }

        return taskInfoRespVO;
    }


    @Override
    public AppTaskInfoRespVO getDetailById(Long id ) {
        validateInfoExists(id);
        TaskInfoDO taskInfoDO = getInfo(id);
        AppTaskInfoRespVO appTaskInfoRespVO = new AppTaskInfoRespVO();
        if (taskInfoDO != null) {

            appTaskInfoRespVO.setId(taskInfoDO.getId()); // 编号
            appTaskInfoRespVO.setAvatar(taskInfoDO.getAvatar()); // 任务图标
            appTaskInfoRespVO.setName(taskInfoDO.getName()); // 任务名称
            appTaskInfoRespVO.setTaskIntroduct(taskInfoDO.getTaskIntroduct()); // 任务简介
            appTaskInfoRespVO.setCategoryId(taskInfoDO.getCategoryId()); // 任务类型
            appTaskInfoRespVO.setRewardScore(taskInfoDO.getRewardScore()); // 奖励积分
            appTaskInfoRespVO.setDayRewardTimes(taskInfoDO.getDayRewardTimes()); // 每天奖励次数
            appTaskInfoRespVO.setMaxRewardTimes(taskInfoDO.getMaxRewardTimes()); // 累计最多奖励次数
            appTaskInfoRespVO.setButtonName(taskInfoDO.getButtonName()); // 按钮名称
            if (taskInfoDO.getFunctionType() != null) {
                appTaskInfoRespVO.setFunctionType(taskInfoDO.getFunctionType()); // 跳转功能函数类型
            }
            if (taskInfoDO.getContentType() != null) {
                appTaskInfoRespVO.setContentType(ContentTypeEnum.findByLabel(taskInfoDO.getContentType()).getValue()); // 内容类型(对应数据字典share_to_type)
            }
            appTaskInfoRespVO.setStatus(taskInfoDO.getStatus()); // 状态(0-启用 1-禁用)
            appTaskInfoRespVO.setContent(taskInfoDO.getContent()); // 详细规则
            appTaskInfoRespVO.setRemark(taskInfoDO.getRemark()); // 备注
            appTaskInfoRespVO.setSeqNo(taskInfoDO.getSeqNo()); // 排序号
            appTaskInfoRespVO.setCreateTime(taskInfoDO.getCreateTime());

            if (taskInfoDO.getShareContent() != null){

                Gson gson = new Gson();
                ShareContent shareContent = gson.fromJson(taskInfoDO.getShareContent(),ShareContent.class);

                Map<String,String> map = new HashMap();
                if (shareContent != null) {
                    if (taskInfoDO.getCategoryId() == 1) { // 邀请新用户

                        map.put("title",shareContent.getTitle());
                        map.put("url",shareContent.getUrl());
                        map.put("img",shareContent.getImg());
                        map.put("desc",shareContent.getDesc());
                    }

                    if (taskInfoDO.getCategoryId() == 2) { // 应用市场评价
                        appTaskInfoRespVO.setContentType(null);
                    }

                    if (taskInfoDO.getCategoryId() == 3) { // 参与活动,添加url
                        map.put("url",shareContent.getUrl());
                        appTaskInfoRespVO.setContentType(null);
                    }

                    if (taskInfoDO.getCategoryId() == 4 || taskInfoDO.getCategoryId() == 5) { //分享好友与朋友圈
                       if ("分享朋友圈纯文本".equals(taskInfoDO.getContentType()) || "分享微信好友纯文本".equals(taskInfoDO.getContentType())) {
                            map.put("title",shareContent.getTitle());
                        }

                        if ("分享朋友圈图片".equals(taskInfoDO.getContentType()) || "分享微信好友图片".equals(taskInfoDO.getContentType())) {
                            map.put("img",shareContent.getImg());
                        }

                        if ("分享朋友圈链接".equals(taskInfoDO.getContentType())|| "分享微信好友链接".equals(taskInfoDO.getContentType())) {
                            map.put("title",shareContent.getTitle());
                            map.put("url",shareContent.getUrl());
                            map.put("img",shareContent.getImg());
                            map.put("desc",shareContent.getDesc());
                        }
                    }
                }


                appTaskInfoRespVO.setShareContent(map); // 内容类型(对应数据字典share_to_type)
            }
        }


        return appTaskInfoRespVO;
    }

    @Override
    public PageResult<TaskInfoRespVO> getInfoPage(TaskInfoPageReqVO pageReqVO) {
        PageResult<TaskInfoDO> pageResult = taskInfoMapper.selectPage(pageReqVO);

        PageResult<TaskInfoRespVO>  pageResult1 = new PageResult<>();
        List<TaskInfoRespVO> list = new ArrayList<>();
        pageResult.getList().stream().forEach(item->{

            TaskInfoRespVO taskInfoRespVO = new TaskInfoRespVO();
            BeanUtils.copyProperties(item,taskInfoRespVO);
            if (item.getShareContent() != null) {
                Gson gson = new Gson();
                ShareContent shareContent =  gson.fromJson(item.getShareContent(),ShareContent.class);
                taskInfoRespVO.setShareContentDetail(shareContent);
            }


            list.add(taskInfoRespVO);
        });

        pageResult1.setList(list);
        pageResult1.setTotal(pageResult.getTotal());

        return new PageResult<TaskInfoRespVO>(pageResult1.getList(), pageResult1.getTotal());

    }

    @Override
    public PageResult<AppTaskInfoRespVO> getTaskPageList(AppTaskInfoPageReqVO pageReqVO) {

        IPage<AppTaskInfoRespVO> pageResult = taskInfoMapper.getTaskPageList(MyBatisUtils.buildPage(pageReqVO),
                null, null, null, null,null);
        return new PageResult<>(pageResult.getRecords(), pageResult.getTotal());
    }


    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void updateStatusEnabled(Long id, Long categoryId, Boolean enabled) {
        // 校验存在
        validateInfoExists(id);
        Long userId = getLoginUserId();
        // 1.把所有启用的均改成禁用
        if (enabled == false) {
            LambdaUpdateWrapper<TaskInfoDO> lambdaUpdateWrapper1 = new LambdaUpdateWrapper();
            lambdaUpdateWrapper1.eq(TaskInfoDO::getStatus, 0);
            lambdaUpdateWrapper1.eq(TaskInfoDO::getCategoryId, categoryId);
            lambdaUpdateWrapper1.set(TaskInfoDO::getStatus, 1);

            lambdaUpdateWrapper1.set(TaskInfoDO::getUpdater, userId);
            lambdaUpdateWrapper1.set(TaskInfoDO::getUpdateTime, LocalDateTime.now());
            taskInfoMapper.update(null, lambdaUpdateWrapper1);
        }

        LambdaUpdateWrapper<TaskInfoDO> lambdaUpdateWrapper2 = new LambdaUpdateWrapper();
        lambdaUpdateWrapper2.eq(TaskInfoDO::getId, id);
        lambdaUpdateWrapper2.set(TaskInfoDO::getStatus, enabled ? 1 : 0);

        lambdaUpdateWrapper2.set(TaskInfoDO::getUpdater, userId);
        lambdaUpdateWrapper2.set(TaskInfoDO::getUpdateTime, LocalDateTime.now());
        taskInfoMapper.update(null, lambdaUpdateWrapper2);
    }



    /**
     * 根据任务id来获取用户是否有条件获取积分
     * @param taskId
     * @return
     */
    @Override
    @Transactional(rollbackFor = {
            Throwable.class,ServiceException.class,Exception.class
    })
    public AppTaskRetRespVO getTaskRewardPointResult(Long taskId) {
        //  1、邀请新用户 2、应用市场评价 3、参与活动 4、分享微信好友 5、分享朋友圈
        LambdaQueryWrapper<TaskInfoDO> taskInfoDOLambdaQueryWrapper = Wrappers.lambdaQuery();
        taskInfoDOLambdaQueryWrapper.eq(TaskInfoDO::getId,taskId);
        taskInfoDOLambdaQueryWrapper.eq(TaskInfoDO::getDeleted,0);
        taskInfoDOLambdaQueryWrapper.eq(TaskInfoDO::getStatus,0);
        TaskInfoDO taskInfoDO = taskInfoMapper.selectOne(taskInfoDOLambdaQueryWrapper);
        if (taskInfoDO == null) {
            throw new ServiceException(405,"查询无任务信息存在，可能任务状态已禁用");
        }

        // 开始时间：当天开始
        LocalDateTime beginTime = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);

        // 结束时间：当天结束
        LocalDateTime endTime = LocalDateTime.of(LocalDate.now(), LocalTime.MAX);

        LocalDateTime[] createTimes = new LocalDateTime[] {beginTime,endTime };
        log.info("*********奖励积分接口，taskId:" + taskId + ",用户id:" + getLoginUserId() + ",起始时间:" +  beginTime.toString() + ",结束时间:" + endTime);


        AppTaskRetRespVO appTaskRetRespVO = new AppTaskRetRespVO();
        appTaskRetRespVO.setTaskId(taskId);
        appTaskRetRespVO.setTaskName(taskInfoDO.getName());
        appTaskRetRespVO.setResult("今日已完成或超过任务设定次数！");

        // 统计用户每天做任务次数
        int dayTasksTimes = taskRewardRecordMapper.getTaskRecords(taskId, getLoginUserId(), createTimes);


        // 统计用户每天做任务获取的积分
        Integer sumDayRewardScore = taskRewardRecordMapper.getUserTaskRewardScore(taskId, getLoginUserId(), createTimes);
        // 统计用户累计做任务次数
        int tasksTimes = taskRewardRecordMapper.getTaskRecords(taskId, getLoginUserId(), null);

        // 统计用户累计做任务获取的积分
        Integer sumRewardScore = taskRewardRecordMapper.getUserSummaryTaskRewardScore(taskId, getLoginUserId(), null);

        if (sumDayRewardScore == null) sumDayRewardScore = 0;

        if (taskInfoDO.getDayRewardTimes() != -1 && taskInfoDO.getDayRewardTimes() <=  dayTasksTimes ) { // 如果在合理次数
            return appTaskRetRespVO;
        }

        if (taskInfoDO.getMaxRewardTimes()  != -1 &&  taskInfoDO.getMaxRewardTimes() <= tasksTimes ) {
            return appTaskRetRespVO;
        }

        StringBuilder sb = new StringBuilder();
        if (taskInfoDO.getDayRewardTimes() == -1 || taskInfoDO.getDayRewardTimes() > dayTasksTimes ) { // 如果在合理次数
            if (taskInfoDO.getRewardScore() <= 0) {
                throw new ServiceException(520,taskInfoDO.getName() + "任务的积分必须大于0");
            }

            if (taskInfoDO.getCategoryId() == 2) { // 如果是应用市场评价
                throw new ServiceException(521,"应用市场类任务不支持调用奖励积分接口");
            }
            TaskRewardRecordDO taskRewardRecordDO = new TaskRewardRecordDO();
            taskRewardRecordDO.setTaskId(taskId);
            taskRewardRecordDO.setUserId(getLoginUserId());
            taskRewardRecordDO.setRewardScore(taskInfoDO.getRewardScore());
            taskRewardRecordDO.setRewardTime(LocalDateTime.now());

            // 添加到审核记录表
            if (taskInfoDO.getCategoryId() == 2) { // 如果是应用评价审核，就需要插入数据
                taskRewardRecordMapper.insertAndGetId(taskRewardRecordDO);
            }

            TaskRewardLogDO taskRewardLogDO = new TaskRewardLogDO();
            taskRewardLogDO.setTaskId(taskRewardRecordDO.getTaskId());
            taskRewardLogDO.setUserId(taskRewardRecordDO.getUserId());
            taskRewardLogDO.setRewardScore(taskRewardRecordDO.getRewardScore());
            taskRewardLogDO.setTaskScreenshot(taskRewardRecordDO.getTaskScreenshot());
            taskRewardLogDO.setRewardTime(taskRewardRecordDO.getRewardTime());
            taskRewardLogDO.setDayRewardTimes(taskInfoDO.getDayRewardTimes());
            taskRewardLogDO.setMaxRewardTimes(taskInfoDO.getMaxRewardTimes());
            taskRewardLogDO.setCreateTime(taskRewardRecordDO.getCreateTime());
            taskRewardLogDO.setCreator(taskRewardRecordDO.getCreator());
            taskRewardLogDO.setUpdateTime(taskRewardRecordDO.getUpdateTime());
            taskRewardLogDO.setUpdater(taskRewardRecordDO.getUpdater());

            rewardLogMapper.insertAndGetId(taskRewardLogDO);

            // 添加到会员积分记录表
            if (taskInfoDO.getCategoryId() == 1) { // 如果是邀请新用户
                memberPointApi.addPoint(getLoginUserId(), taskInfoDO.getRewardScore(), MemberPointBizTypeEnum.INVITE_NEWUSER_POINT.getType(), String.valueOf(taskRewardLogDO.getId()));
            }

            if (taskInfoDO.getCategoryId() == 3) { // 如果是参与活动
                memberPointApi.addPoint(getLoginUserId(), taskInfoDO.getRewardScore(), MemberPointBizTypeEnum.JOIN_ACTIVITY_TASK.getType(), String.valueOf(taskRewardLogDO.getId()));
            }
            if (taskInfoDO.getCategoryId() == 4) { // 如果是分享微信好友
                memberPointApi.addPoint(getLoginUserId(), taskInfoDO.getRewardScore(), MemberPointBizTypeEnum.SHARE_WEIXIN_TASK.getType(), String.valueOf(taskRewardLogDO.getId()));
            }
            if (taskInfoDO.getCategoryId() == 5) { // 如果是分享朋友圈
                memberPointApi.addPoint(getLoginUserId(), taskInfoDO.getRewardScore(), MemberPointBizTypeEnum.SHARE_FRIEND_TASK.getType(), String.valueOf(taskRewardLogDO.getId()));
            }

            if (taskInfoDO.getRewardScore() > 0) {
                sb.append("恭喜获得" + taskInfoDO.getRewardScore() + "积分任务奖励！");
                appTaskRetRespVO.setResult(sb.toString());
            }
        }


        log.info("***taskid:{},userid:{},maxRewardTimes:{},tasksTimes:{},sumRewardScore:{}",  taskId, getLoginUserId(),taskInfoDO.getMaxRewardTimes(),tasksTimes,sumRewardScore);
        if (sumRewardScore == null) sumRewardScore = 0;

//        if (taskInfoDO.getMaxRewardTimes()  == -1 ||  taskInfoDO.getMaxRewardTimes() > tasksTimes ) {
//            if (sumRewardScore > 0) {
//                sb.append("累计已获取" + sumRewardScore + "积分!");
//                appTaskRetRespVO.setResult(sb.toString());
//            }
//        }

        return appTaskRetRespVO;

    }


    
}